package com.sie.framework.module;

import android.graphics.Bitmap;
import android.util.Base64;
import android.util.Log;

import com.sie.framework.constconfig.Config;
import com.sie.framework.constconfig.ErrorDefine;
import com.sie.framework.appinterface.APDU_RESP;
import com.sie.framework.listen.FingerPrintListen;
import com.sie.tools.ByteTool;
import com.sie.tools.FingerUnit;
import com.sie.tools.SingletonThreadPool;

import java.util.concurrent.ExecutorService;

/**
 * Created by zhq on 2015/12/10.
 */
public class FingerPrintModule extends CommonModule {
	private final String tag = "FingerPrintModule";
	public int slot[] = new int[20];
	private FingerPrintListen callback;
	private static FingerPrintModule module = null;
	private FingerPrintThread Finger_Thread = null;
	private ReadWrite mReadWrite = null;
	private static int fingerType = 0;
	public static final int OPCODE_GETIMAGE_TEST = 7;
	private byte imageData[] = new byte[40000];
	private Bitmap fingerPrintBMP = null;
	private static ExecutorService threadPool = SingletonThreadPool
			.getInstance();
	private boolean lockFlag = false;

	private FingerPrintModule() {

	}

	@Override
	public void closeModule(boolean isConnected) {
		Log.e(tag, "closeModule");
		if (null != Finger_Thread && !Finger_Thread.isThreadFinished()) {
			Finger_Thread.setFlag(false);
//			while (!Finger_Thread.isThreadFinished()) {
//				SystemClock.sleep(10);
//			};

			Finger_Thread = null;
		}
		if (isConnected) {
			api.TCD_Close();
			
		}
		lockFlag = false;
	}

	@Override
	public boolean isFinish() {
		if (Finger_Thread == null || Finger_Thread.isThreadFinished()) {
			return true;
		} else {
			return false;
		}
	}

	public void startRead(final int printType) {
		Log.e(tag, "startRead");
		Runnable r = new Runnable() {
			@Override
			public void run() {
				if (null != Finger_Thread && !Finger_Thread.isThreadFinished()) {
					Finger_Thread.setFlag(false);
					while (!Finger_Thread.isThreadFinished()) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					Finger_Thread = null;
				}
				while (lockFlag) {
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				fingerType = printType;
				Finger_Thread = new FingerPrintThread();
				Finger_Thread.start();
				Log.e(tag, "start!!!!");
			}
		};
		threadPool.submit(r);
	}

	public void setCallback(FingerPrintListen callback) {
		this.callback = callback;
	}

	public static FingerPrintModule getInstance() {
		if (module == null) {
			module = new FingerPrintModule();
		}
		return module;
	}

	public void fingerImg() {
		Log.e(tag, "startRead");
		Runnable r = new Runnable() {
			@Override
			public void run() {
				if (null != mReadWrite && !mReadWrite.isThreadFinished()) {
					while (!mReadWrite.isThreadFinished()) {
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					mReadWrite = null;
				}
				while (lockFlag) {
					try {
						Thread.sleep(1);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				mReadWrite = new ReadWrite(0);
				mReadWrite.start();
				Log.e(tag, "start!!!!");
			}
		};
		threadPool.submit(r);
	}

	@Override
	public int OpenModule() {
		int ret = 0;
		for (int p = 0; p < 5; p++) {
			ret = api.TCD_Open();
			if (ret == 0) {
				break;
			} else {
				api.TCD_Close();
				//ChannelInstance.resetChannel();
			}
		}
		return ret;
	}

	private class ReadWrite extends Thread {
		private int mOpCode;
		int ret;
		private boolean isThreadFinished = false;

		public boolean isThreadFinished() {
			return isThreadFinished;
		}

		public ReadWrite(int OpCode) {
			mOpCode = OpCode;
		}

		@Override
		public void run() {
			synchronized (this) {
				isThreadFinished = false;
				for (int i = 0; i < 10; i++) {
					int iRetCode = api.TCD_Open();
					if (iRetCode == 0) {
						break;
					}
				}
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
				byte packIndex = 0;
				byte[] finishFlag = new byte[1];
				byte dataOut[] = new byte[1024];
				int[] lenOut = new int[1];
				int dataIndex = 0;
				finishFlag[0] = 1;
				long now  =0L;
				while (finishFlag[0] == 1) {
					if(packIndex==1){
						callback.onStart();
						now = System.currentTimeMillis();
					}
					for (int i = 0; i < 2; i++) {
						ret = api.Lib_FpGetImg(packIndex, finishFlag, dataOut,
								lenOut);
						Log.e(tag, "Lib_FpGetImgT:" + ret);
						if (ret == 0) {
							break;
						}
					}
					Log.e(tag,
							"finishFlag:"
									+ ByteTool.byteToHexString(finishFlag[0]));
					if (ret != 0) {
						Log.e(tag, "Lib_FpGetImg fail, ret = " + ret);
						callback.onFail(ErrorDefine.ERR_MODULE_FINGET, "指纹模块异常");
						isThreadFinished = true;
						Log.e(tag, "1.获取图像失败" + ret);
						return;
					} else if (finishFlag[0] == 0) {
						System.arraycopy(dataOut, 0, imageData, dataIndex,
								lenOut[0]);
						dataIndex += lenOut[0];
						fingerPrintBMP = api.CreateBMP(imageData, dataIndex,
								"/sdcard/", "FingerPrint.bmp");
						Log.e(tag, "Lib_FpGetImg  totallen = " + dataIndex);
						long finish = System.currentTimeMillis();
						if (fingerPrintBMP != null) {
							Log.e(tag, "ImguseTime:" + (finish - now) + "ms");
							
							callback.onGetImgSucc(fingerPrintBMP);
						} else {
							callback.onFail(ErrorDefine.ERR_MODULE_FINGET, "指纹模块异常");
						}
						Log.e(tag, "2" + ret);
						break;
					} else {
						packIndex++;
						System.arraycopy(dataOut, 0, imageData, dataIndex,
								lenOut[0]);
						dataIndex += lenOut[0];
						Log.e(tag, "Lib_FpGetImg  packIndex = " + packIndex);
						Log.e(tag, "Lib_FpGetImg  currentLen = " + dataIndex);
						Log.e(tag, "3");
						callback.onGetImgProgress(dataIndex);
						// callback.onGetImgProgress((dataIndex*100/30400));
					}
				}
				ret = api.TCD_Close();
				isThreadFinished = true;
			}
			// setCancle();
		}
	}

	public class FingerPrintThread extends Thread {
		private boolean runFlag = true;
		private boolean m_bThreadFinished = false;

		public boolean isThreadFinished() {
			return m_bThreadFinished;
		}

		public FingerPrintThread() {
			runFlag = true;
		}

		public void setFlag(boolean flag) {
			runFlag = flag;
		}

		@Override
		public void run() {
			int ret = 1;
			ret = OpenModule();
			if (ret != 0) {
				if (callback != null) {
					callback.onFail(ErrorDefine.ERR_MODULE_FINGET, "指纹模块异常");
				}
				api.IDCard_Close();
				m_bThreadFinished = true;
				return;
			}
			if (callback != null) {
				callback.onStart();
			}
			try {
				synchronized (this) {
					while (runFlag) {
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						APDU_RESP ApduResp_TCD = new APDU_RESP();
						ret = api.TCD_Read_Test(ApduResp_TCD);
						if (0 == ret) {
							String strInfo = "";
							byte[] fingerByte = new byte[ApduResp_TCD.LenOut];
							try {
								System.arraycopy(ApduResp_TCD.DataOut, 0,
										fingerByte, 0, ApduResp_TCD.LenOut);
								Log.e("fingerCode:",
										ByteTool.byte2hex(fingerByte));
								if (fingerType == Config.WELL_FINGER) {
									strInfo = FingerUnit
											.parseWellcom(fingerByte);
								} else if (fingerType == Config.SHENGYE_FINGER) {
									strInfo = Base64.encodeToString(fingerByte,
											Base64.NO_WRAP);
								} else {
									strInfo = Base64.encodeToString(fingerByte,
											Base64.NO_WRAP);
								}
							} catch (ArrayIndexOutOfBoundsException e) {
								continue;
							}
							callback.onRead(strInfo);
							callback = null;
							runFlag = false;
							api.TCD_Close();
							break;
						} 
					}
//					if(api != null){
//						api.TCD_Close();
//						//Log.e("GJ", "指纹超时已经下电");
//					}
				}
			} finally {
				m_bThreadFinished = true;
			}

		}

	}

}
